import requests
import re
import json
import os
import sys
from pyquery import PyQuery as pq

BASE_URL = 'https://www.acfun.cn/u/'
BASE_DIR = os.path.realpath(os.path.dirname(sys.argv[0]))
CURRENT_DIR = BASE_DIR + '\\videos\\'


# 获取该up主的主页共有多少页数据
def max_page_number(url, headers):
    try:
        r = requests.get(url, headers=headers)
        doc = pq(r.text)

        video_num = doc('ul.tags li.active span').text()
        print(f'该Up主共有：{int(video_num)}个视频')
        max_page = int(video_num)//20 + 1
        return max_page  # 成功解析到该up主有多少页视频
    except:
        print('不存在这样一个up主')
        return -1  # 若没有解析成功就返回-1


# 获取一页内的所有视频的url
def get_one_page(url, headers, params):
    try:
        video_list = []
        r = requests.get(url, headers=headers, params=params)
        videos = re.findall('/ac(.*?) ', r.text)
        for video in videos:
            ac = video.replace('\\"', '')
            video_list.append('https://www.acfun.cn' + '/v/ac' + ac)
        return video_list
    except:
        return []


# 获取单个视频的m3u8_url地址
def get_video(url, headers):
    try:
        r = requests.get(url=url, headers=headers)
        json_str = re.findall(r'window.videoInfo = (.*?);', r.text)[0]
        json_data = json.loads(json_str)
        # 获取视频名称
        title = json_data.get('title')
        title = ''.join(re.findall(r'[\u4e00-\u9fa5]', title))
        m3u8_url = json.loads(json_data['currentVideoInfo']['ksPlayJson'])['adaptationSet'][0]['representation'][2]['url']
        print(f'正在爬取【{title}】视频')
        return m3u8_url, title
    except:
        return ()


# 下载保存单个视频
def save_data(info, headers):
    # 判断视频是否已经存在
    if os.path.exists(CURRENT_DIR+f'{info[1]}.mp4'):
        print('保存失败==视频已存在\n')
        return
    # 获取1080p视频内容
    resp = requests.get(url=info[0], headers=headers)
    ts_list = re.sub(r'#E.*', '', resp.text).split()
    for ts in ts_list:
        ts = 'https://ali-safety-video.acfun.cn/mediacloud/acfun/acfun_video/' + ts
        response = requests.get(ts, headers=headers)
        with open(CURRENT_DIR + info[1] + '.mp4', 'ab') as file:
            file.write(response.content)
    print(f'\n保存成功=={info[1]}', end='\t')


def main():
    # 判断一下文件夹和视频文件有无重复
    if os.path.exists(CURRENT_DIR):
        print('视频文件存放在：', CURRENT_DIR, end='\n')
    else:
        os.mkdir(CURRENT_DIR)
        print('视频文件存放在：', CURRENT_DIR, end='\n')
    # 定义一系列爬取变量
    user_id = input('请输入A站（https://www.acfun.cn/）up主的UID（例如：16380981）\n>>>:')
    user_url = BASE_URL + user_id
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
    }

    # 获取这个up共有多少页视频
    page_number_url = user_url
    num = max_page_number(page_number_url, headers)
    v_count = int(input('请问你要爬取多少个视频：'))
    count = 0
    for page in range(1, num+1):
        # params里面的数字不区分整型还是字符串
        params = {
            'quickViewId': 'ac-space-video-list',
            'reqID': page + 1,
            'ajaxpipe': '1',
            'type': 'video',
            'order': 'newest',
            'page': page,
            'pageSize': '20',
            't': '1657697161556',
        }
        # 获取一页内的所有视频的url
        one_page_url = get_one_page(user_url, headers, params)
        if one_page_url:
            # 获取up主空间里一页中所有视频的m3u8_url
            for url in one_page_url:
                info = get_video(url, headers)
                if info:
                    # 下载这个视频
                    save_data(info, headers)
                    count += 1  # 记录保存了几个视频
                    print('总进度={:.2f}%\n'.format((count / v_count) * 100))  # 记录总进度

                    if v_count == count:
                        # 如果保存的视频数量等于你想要的数量，就停止
                        sys.exit()
                else:
                    print('获取视频失败')
                    count += 1
                    if v_count == count:
                        # 如果保存的视频数量等于你想要的数量，就停止
                        sys.exit()
        else:
            print('这个up主没有视频')


if __name__ == '__main__':
    main()
